package com.qiangesoft.blog.core.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qiangesoft.blog.common.mvc.PageQuery;
import com.qiangesoft.blog.common.mvc.PageResultVO;
import com.qiangesoft.blog.common.utils.DateUtils;
import com.qiangesoft.blog.core.entity.BlogSource;
import com.qiangesoft.blog.core.mapper.BlogSourceMapper;
import com.qiangesoft.blog.core.pojo.query.SourceQueryDTO;
import com.qiangesoft.blog.core.pojo.vo.ArticleInfoVO;
import com.qiangesoft.blog.core.pojo.vo.BlogSourceSimpleVO;
import com.qiangesoft.blog.core.pojo.vo.SourceInfoVO;
import com.qiangesoft.blog.core.service.IBlogSourceService;
import com.qiangesoft.blog.file.model.FileInfoVo;
import com.qiangesoft.blog.file.service.ISysFileInfoService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 源码 服务实现类
 * </p>
 *
 * @author qiange
 * @since 2023-06-08
 */
@Service
@RequiredArgsConstructor
public class BlogSourceServiceImpl extends ServiceImpl<BlogSourceMapper, BlogSource> implements IBlogSourceService {

    private final ISysFileInfoService sysFileInfoService;

    @Override
    public List<BlogSourceSimpleVO> listTopDownloadSource(Integer limit) {
        List<BlogSourceSimpleVO> results = new ArrayList<>();

        LambdaQueryWrapper<BlogSource> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BlogSource::getIsPublish, true)
                .eq(BlogSource::getIsSecret, false)
                .orderByDesc(BlogSource::getDownloadNum).last("limit " + limit);
        List<BlogSource> sourceList = baseMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(sourceList)) {
            return results;
        }

        List<Long> fileIds = sourceList.stream().map(BlogSource::getSourceFileId).collect(Collectors.toList());
        Map<Long, String> fileMap = sysFileInfoService.getFileInfoByIds(fileIds).stream().collect(Collectors.toMap(FileInfoVo::getFileId, FileInfoVo::getStoreUrl));
        for (BlogSource blogSource : sourceList) {
            BlogSourceSimpleVO vo = new BlogSourceSimpleVO();
            vo.setId(blogSource.getId());
            vo.setTitle(blogSource.getTitle());
            vo.setAvatar(blogSource.getAvatar());
            vo.setDownloadNum(blogSource.getDownloadNum());
            vo.setDownloadUrl(fileMap.get(blogSource.getSourceFileId()));
            results.add(vo);
        }
        return results;
    }

    @Override
    public PageResultVO<SourceInfoVO> listSource(PageQuery pageQuery) {
        Integer pageNum = pageQuery.getPageNum();
        Integer pageSize = pageQuery.getPageSize();
        PageResultVO<SourceInfoVO> pageResult = new PageResultVO<>();
        pageResult.setPageNum(pageNum);
        pageResult.setPageSize(pageSize);

        LambdaQueryWrapper<BlogSource> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BlogSource::getIsPublish, true)
                .orderByDesc(BlogSource::getIsStick);

        Page<BlogSource> page = baseMapper.selectPage(new Page<>(pageNum, pageSize), queryWrapper);
        List<BlogSource> records = page.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return pageResult;
        }

        List<SourceInfoVO> voList = new ArrayList<>();
        for (BlogSource record : records) {
            SourceInfoVO vo = new SourceInfoVO();
            vo.setId(record.getId());
            vo.setTitle(record.getTitle());
            vo.setAvatar(record.getAvatar());
            vo.setContent(record.getContent());
            vo.setContentMd(record.getContentMd());
            vo.setIsStick(record.getIsStick());
            vo.setCreateTime(DateUtils.localDateTimeToDate(record.getCreateTime()));
            vo.setQuantity(record.getQuantity());
            voList.add(vo);
        }
        pageResult.setTotal(page.getTotal());
        pageResult.setPages(page.getPages());
        pageResult.setResults(voList);
        return pageResult;
    }

    @Override
    public ArticleInfoVO getSource(Long id) {
        BlogSource source = this.getById(id);

        ArticleInfoVO vo = new ArticleInfoVO();
        BeanUtils.copyProperties(source, vo);
        return vo;
    }

    @Override
    public PageResultVO<BlogSource> pageSource(PageQuery pageQuery, SourceQueryDTO sourceQuery) {
        PageResultVO<BlogSource> pageResultVO = new PageResultVO<>();
        Integer pageNum = pageQuery.getPageNum();
        Integer pageSize = pageQuery.getPageSize();
        pageResultVO.setPageNum(pageNum);
        pageResultVO.setPageSize(pageSize);

        LambdaQueryWrapper<BlogSource> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(sourceQuery.getTitle()), BlogSource::getTitle, sourceQuery.getTitle())
                .eq(!ObjectUtils.isEmpty(sourceQuery.getIsPublish()), BlogSource::getIsPublish, sourceQuery.getIsPublish())
                .orderByDesc(BlogSource::getId);
        Page<BlogSource> page = baseMapper.selectPage(new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize()), queryWrapper);

        pageResultVO.setTotal(page.getTotal());
        pageResultVO.setPages(page.getPages());
        pageResultVO.setResults(page.getRecords());
        return pageResultVO;
    }

    @Override
    public BlogSource getSourceById(Long id) {
        BlogSource blogSource = baseMapper.selectById(id);
        FileInfoVo info = sysFileInfoService.getFileInfoById(blogSource.getSourceFileId());
        blogSource.setSourceFileInfo(info);
        return blogSource;
    }

    @Override
    public void insertSource(BlogSource source) {
        baseMapper.insert(source);
    }

    @Override
    public void updateSource(BlogSource source) {
        baseMapper.updateById(source);
    }

    @Override
    public void deleteSource(Long id) {
        baseMapper.deleteById(id);
    }

    @Override
    public void deleteBatchSource(List<Long> ids) {
        baseMapper.deleteBatchIds(ids);
    }

    @Override
    public void putTopSource(BlogSource source) {
        baseMapper.updateById(source);
    }

    @Override
    public void publishAndShelf(BlogSource source) {
        baseMapper.updateById(source);
    }
}
